home *** CD-ROM | disk | FTP | other *** search
- PROGRAM VTview;
- FROM vt USES pagelist,decode,sys; {$opt q,s+,i+ }
- { Stellt roh abgespeicherte Videotextseiten auf einem eigenen Screen dar. }
- CONST version = '$VER: VTview 1.6 (19.06.95)';
-
- {$incl "dos.lib", "workbench/startup.h", "icon.lib" }
-
- VAR j, timing, countdown, anzseiten: integer;
- auto, cycle, conceal: boolean;
- taste,ch: Char;
- titel,s: Str80; STATIC;
- l: Long;
-
- { ###################################################################### }
- { ------------------------- Dateibehandlung ---------------------------- }
- { ###################################################################### }
-
- FUNCTION filetype(name: Str80): Integer;
- { Typcodierung: }
- { -1: Datei existiert nicht }
- { 0: unbekannter Typ (vermutlich roher ASCII-Text) }
- { 1: programmeigener Typ 'VTPG'=$56545047 }
- { 2: AmigaDOS-Programmdatei $000003F3 }
- { 3: IFF-Datei 'FORM'=$464F524D }
- { 4: Workbench-Icon $E310 }
- VAR head: Long;
- i: Integer;
- ch: Char;
- datei: Text;
- BEGIN
- Reset(datei,name);
- IF IOresult=0 THEN BEGIN
- filetype := 0;
- head := 0;
- FOR i := 1 TO 4 DO BEGIN
- Read(datei,ch);
- head := head SHL 8 + Ord(ch);
- IF (i=2) AND (head=$E310) THEN filetype := 4;
- END;
- IF head=$56545047 THEN filetype := 1;
- IF head=$000003F3 THEN filetype := 2;
- IF head=$464F524D THEN filetype := 3;
- Close(datei);
- END ELSE
- filetype := -1;
- END;
-
- FUNCTION getpages(filename: Str80): Integer;
- { Alle VT-Seiten aus einer VTPG-Datei einlesen und in die Seitenliste }
- { einreihen. Rückgabewert: Anzahl der gelesenen Seiten }
- VAR i,j, gelesen: Integer;
- bytes: ^ARRAY[1..41] OF Char;
- datei: Text;
- zeile: Str80;
- seite: p_onepage;
- c: Char;
- PROCEDURE findword;
- { Hilft, zeile in Worte zu zerlegen. Parameter j: Startpunkt, Ergebnis: }
- { i: 1. Zeichen des Wortes, j: 1. Trennzeichen dahinter }
- BEGIN
- i := j; WHILE (zeile[i]=' ') AND (zeile[i]<>#0) DO Inc(i);
- j := i + 1; WHILE NOT (zeile[j] IN [' ',#0]) DO Inc(j);
- END;
- BEGIN
- gelesen := 0;
- Reset(datei,filename);
- IF (IOresult<>0) THEN { Datei existiert nicht }
- Exit;
- Buffer(datei,200);
- WHILE NOT EoF(datei) DO BEGIN
- REPEAT
- ReadLn(datei,zeile);
- UNTIL (zeile='VTPG') OR EoF(datei);
- if zeile='VTPG' THEN BEGIN
- New(seite);
- FOR i := 0 to 23 DO BEGIN
- bytes := Ptr(^seite^.chars[40*i]);
- BlockRead(datei,bytes^,40);
- ReadLn(datei);
- END;
- ReadLn(datei,zeile); j := 1;
- findword; seite^.pg := hexval(Copy(zeile,i,j-i));
- findword; seite^.sp := hexval(Copy(zeile,i,j-i));
- findword; seite^.cbits := hexval(Copy(zeile,i,j-i));
- add_to_list(seite); Inc(gelesen);
- END;
- END;
- Close(datei);
- getpages := gelesen;
- END;
-
- { ###################################################################### }
- { -------------------------- Bildschirmausgabe ------------------------- }
- { ###################################################################### }
-
- PROCEDURE writepage(seite: p_onepage, verdeckt: Boolean);
- { Seite am Bildschirm ausgeben }
- CONST xoff = 1;
- VAR zeile,i,j,j0: Integer;
- farbe,farbe0: Word;
- out: bigstring;
- x: Byte;
- s,attrib: str80;
- dblheight,rastergfx,special: Boolean;
- normal: String[10];
- BEGIN
- normal := #155'0;3'+colperms[7]+';4'+colperms[0]+'m'; { weiß auf schwarz }
- dblheight := False; rastergfx := False;
- seite^.chars[0] := 2; { Seitennummer zunächst grün }
- for i := 0 to 24 do begin
- zeile := i MOD 24;
- IF i=24 THEN BEGIN
- { Überreste von doppelthohen Zeichen in der untersten Zeile einer }
- { alten Seite löschen: }
- IF NOT dblheight THEN BEGIN
- GotoXY(xoff,25); Write(#155'0m',blank40,' ');
- END;
- { 1. Zeile nochmal, mit weißer Seitennummer: }
- IF seite<>Nil THEN seite^.chars[0] := 7;
- dblheight := False;
- END;
- IF dblheight THEN
- { auf eine doppelthohe Zeile folgt nur eine leere Zeile }
- dblheight := False
- ELSE BEGIN
- { normale Zeile ausgeben }
- IF seite<>Nil THEN
- decode_line(seite, zeile, verdeckt, out, attrib, dblheight, rastergfx)
- ELSE
- out := blank40;
- GotoXY(xoff,zeile+1); Write(normal,out,normal,' ');
- IF rastergfx THEN BEGIN { Zeile, die gerasterte Grafikzeichen enthält }
- special := False; farbe := 0;
- FOR j := 0 TO 39 DO BEGIN { zu rasternde Abschnitte suchen }
- farbe0 := farbe; farbe := Ord(attrib[j+1]);
- IF (farbe<>farbe0) AND special THEN BEGIN
- raster_line(zeile+1,xoff+j0,xoff+j-1,farbe0 AND 7);
- j0 := j; special := (farbe AND 16<>0);
- END;
- IF (farbe AND 16<>0) AND NOT special THEN BEGIN
- j0 := j; special := True;
- END;
- END;
- IF special THEN
- raster_line(zeile+1,xoff+j0,xoff+39,farbe0 AND 7);
- END;
- IF dblheight THEN BEGIN { Handhabung doppelthoher Zeilen }
- special := False;
- FOR j := 1 TO Length(out) DO BEGIN { alles außer den ANSI-Codes }
- { entfernen -> erzeugt Kopie der Hintergrundfarben der Zeile }
- IF out[j] = #155 THEN special := True;
- IF NOT special THEN out[j] := ' ';
- IF out[j] = 'm' THEN special := False;
- END;
- GotoXY(xoff,zeile+2); Write(normal,out,normal,' ');
- special := False;
- FOR j := 0 TO 39 DO { doppelthohe Abschnitte suchen }
- CASE seite^.chars[40*zeile+j] OF
- 13: BEGIN j0 := j; special := True; END;
- 12: IF special THEN BEGIN
- stretch_line(zeile+1,xoff+j0,xoff+j); special := False;
- END;
- OTHERWISE;
- END;
- IF special THEN
- stretch_line(zeile+1,xoff+j0,79);
- END;
- END;
- lastkey := readkey; { Taste: Abbruch und Rückmeldung ans HP }
- intui_events; { kann nicht schaden }
- IF (lastkey<>chr(0)) OR stop THEN
- Exit;
- END;
- END;
-
- { ###################################################################### }
- { -------------------------- Initialisierungen ------------------------- }
- { ###################################################################### }
-
- PROCEDURE get_args;
- { Wertet CLI- oder WorkBench-Argumente aus: Die spezifizierten Dateien }
- { werden mit getpages() eingelesen. }
- { ToolTypes: CLI-Parameter: }
- { MODE=MAN|AUTO|CYCLE -a -c }
- { FLAGS=REVEAL|CONCEAL -r }
- { TIMING=<secs> -t<secs> }
- VAR c: char;
- s: bigstring;
- len,i,j,ok: integer;
- hail: p_WBStartup;
- arg: p_WBArg;
- olddir: BPTR;
- icon: p_DiskObject;
- entry: Str;
- name: Str80;
- FUNCTION is_space(ch: Char): Boolean;
- BEGIN is_space := (ch=' ') OR (ch=#9) OR (ch=#10) OR (ch=#13); END;
- BEGIN
- conceal := True;
- auto := False;
- cycle := False;
- timing := 2;
- anzseiten := 0;
- IF fromWB then BEGIN
- OpenLib(IconBase,'icon.library',0);
- hail := StartupMessage;
- arg := hail^.sm_ArgList;
- for i := 1 to hail^.sm_NumArgs do BEGIN
- olddir := CurrentDir(arg^.wa_Lock);
- name := arg^.wa_Name;
- if filetype(name)=1 THEN { nur VTPG-Dateien lesen }
- anzseiten := anzseiten + getpages(name);
- icon := GetDiskObject(arg^.wa_Name);
- if icon<>Nil then BEGIN
- entry := FindToolType(icon^.do_ToolTypes, 'MODE');
- IF ptr(entry)<>Nil THEN BEGIN
- IF MatchToolValue(entry,'MAN') THEN auto := False;
- IF MatchToolValue(entry,'AUTO') THEN BEGIN
- auto := True; cycle := False; END;
- IF MatchToolValue(entry,'CYCLE') THEN BEGIN
- auto := True; cycle := True; END;
- END;
- entry := FindToolType(icon^.do_ToolTypes, 'FLAGS');
- IF ptr(entry)<>Nil THEN BEGIN
- IF MatchToolValue(entry,'REVEAL') THEN conceal := False;
- IF MatchToolValue(entry,'CONCEAL') THEN conceal := True;
- END;
- entry := FindToolType(icon^.do_ToolTypes, 'TIMING');
- if ptr(entry)<>Nil then
- Val(entry,timing,ok);
- FreeDiskObject(icon);
- END;
- olddir := CurrentDir(olddir);
- { auf nächsten WBArg-Zeiger zugreifen: }
- arg := ptr(long(arg)+SizeOf(WBArg));
- END;
- CloseLib(IconBase);
- end else if ParameterLen>0 then BEGIN
- s := copy(ParameterStr,1,ParameterLen);
- len := length(s);
- { Parameterzeile in Worte zerlegen, wie der argv[] in C es schon ist :-( }
- i := 1; while i<=len do BEGIN
- while is_space(s[i]) do Inc(i);
- j := i + 1;
- if s[i]='"' then BEGIN
- Inc(i); while (s[j]<>'"') AND (j<=len) do Inc(j);
- end else BEGIN
- while NOT is_space(s[j]) AND (j<=len) do Inc(j);
- END;
- { Zeiger i: 1. Zeichen des Wortes, j: 1. Trennzeichen dahinter }
- if s[i]='-' then BEGIN
- i := i+2;
- case s[i-1] of
- 't': Val(copy(s,i,j-i),timing,ok);
- 'r': conceal := False;
- 'a': auto := True;
- 'c': BEGIN auto := True; cycle := True; END;
- otherwise BEGIN
- writeln('usage:');
- writeln('VTview <file> <file> ... -r[eveal] -a[uto] -c[ycle] -t<secs> ');
- writeln('with <file> containing raw VideoText pages ("VTPG" format)');
- END;
- END;
- END ELSE
- IF filetype(copy(s,i,j-i))=1 THEN
- anzseiten := anzseiten + getpages(copy(s,i,j-i))
- ELSE
- Writeln('Keine VTPG-Datei: ',copy(s,i,j-i));
- i := j + 1;
- END;
- END;
- END;
-
- { ###################################################################### }
- { ------------------ Hauptprogramm/Ereignisverwaltung ------------------ }
- { ###################################################################### }
-
- PROCEDURE handle_escseq(chars: str80);
- { wie handle_key, aber für die ESC-Sequenzen der Sondertasten }
- VAR i,page,page2: Integer;
- BEGIN
- { Cursor: Seitenliste durchblättern }
- IF Pos(chars,'ABCDST')>0 THEN BEGIN
- IF thispage<>Nil THEN
- CASE chars[1] OF
- 'A': IF (thispage^.prev<>Nil) THEN
- thispage := thispage^.prev;
- 'B': IF (thispage^.next<>Nil) THEN
- thispage := thispage^.next;
- 'S': thispage := next_magazine(thispage);
- 'T': thispage := prev_magazine(thispage);
- 'C': WHILE (thispage^.next<>Nil) DO
- thispage := thispage^.next;
- 'D': thispage := root;
- OTHERWISE;
- END;
- writepage(thispage,conceal);
- END;
- END;
-
- PROCEDURE handle_key(key: char);
- VAR j,ok,ft: integer;
- s: Str80;
- BEGIN
- case key of
- #27: stop := True;
- #127: if thispage<>Nil then BEGIN { Del: eine Seite löschen }
- del_from_list(thispage);
- writepage(Nil,true);
- END;
- ' ': writepage(thispage,true);
- '?': writepage(thispage,false);
- #155: BEGIN { Sondertasten auswerten }
- s := '';
- REPEAT ch := readkey; s := s + ch; UNTIL ch >= '@';
- handle_escseq(s);
- END;
- OTHERWISE;
- END;
- END;
-
- BEGIN { Hauptprogramm }
- get_args; { Parameter holen, Seiten einlesen }
- titel := Copy(version,1,17)+' ('+IntStr(anzseiten)+' pages) ESC to quit';
- colperm := $01234567; colperms := '01234567';
- AddExitServer(sysclean); sysinit(titel);
- Write(#155'0 p'); { Cursor aus }
- countdown := timing;
- lastkey := #0; stop := False;
- thispage := root;
- writepage(thispage,conceal);
- REPEAT
- intui_events; { Msg-Port abfragen }
- IF lastkey=#0 THEN
- taste := readkey
- ELSE BEGIN
- taste := lastkey; lastkey := #0;
- END;
- IF taste<>#0 THEN BEGIN
- auto := False;
- handle_key(taste)
- END ELSE IF auto THEN BEGIN
- Delay(50); Dec(countdown);
- IF countdown<=0 THEN
- IF thispage<>Nil THEN BEGIN
- IF thispage^.next=Nil THEN
- IF cycle THEN thispage := root ELSE stop := True
- ELSE
- thispage := thispage^.next;
- IF NOT stop THEN BEGIN
- writepage(thispage,conceal);
- countdown := timing;
- END;
- END ELSE
- stop := True;
- END ELSE
- l := Wait(-1);
- UNTIL stop;
- SetStdIO(Nil); CloseConsole(Con);
- kill_list; sysclean;
- END.
-
-